package org.bhf.service;

/**
 * Copyright (c) 2007, Blue Hole Software. All rights reserved.
 * Code licensed under the Apache 2.0 License:
 * http://www.apache.org/licenses/
 */

import org.bhf.util.AnnotationAccess;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Configuration for a <code>Component</code> class. Note that a <code>Component</code> MUST also include
 * a <code>ServiceName</code> annotation.
 */
@Documented
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public @interface ComponentInfo
{
    /**
     * Utility accessors for <code>ComponentInfo</code>
     * @exclude
     */
    public static final class Util
    {
        static final Class<ComponentInfo> clazz = ComponentInfo.class;

        /**
         * Obtain the <code>ServiceName</code> annotation for the specified <code>Class</code>.
         * @param componentClass the target <code>Class</code>.
         * @return the <code>ComponentInfo</code> annotation for the specified <code>Class</code>
         *      if it exists; otherwise <code>null</code>.
         */
        public static ComponentInfo get( final Class<? extends Component> componentClass )
        {
            return AnnotationAccess.getAnnotation( componentClass, ComponentInfo.Util.clazz );
        }

        /**
         * Returns <code>true</code> if the specified class is a cacheable <code>ComponentInfo</code>.
         * @param componentClass The <code>ComponentInfo</code> <code>Class</code>.
         * @return <code>true</code> if the specified class is a cacheable <code>ComponentInfo</code>.
         */
        public static boolean       isCachedServerSide( final Class<? extends Component> componentClass )
        {
            final ComponentInfo serviceInfo = ComponentInfo.Util.get( componentClass );
            return serviceInfo != null && serviceInfo.cachedServerSide();
        }

        /**
         * Returns the event interface (Event Group) associated with this <code>Component</code>. WIll be <code>null</code>
         * if not defined.
         * @param componentClass The <code>ComponentInfo</code> <code>Class</code>.
         * @return the event interface (Event Group) associated with this <code>Component</code>.
         */
        public static Class<?>      getEventGroup( final Class<? extends Component> componentClass )
        {
            final ComponentInfo serviceInfo = ComponentInfo.Util.get( componentClass );

            if( serviceInfo == null )
                return null;

            final Class<?> events = serviceInfo.eventGroup();

            return events != null && events.isInterface() ? events : null;
        }

        /**
         * Return the name of this <code>ServiceName</code>.
         * @param serviceClass The <code>ServiceName</code> <code>Class</code>.
         * @return The name of this <code>ServiceName</code>.
         */
        public static String        getName( final Class<? extends Component> serviceClass )
        {
            return Service.Util.getName( serviceClass );
        }
    }

    /**
     * Indicate that the <code>Component</code> is to be cached server side.  By default,
     * <code>Component</code>s are not cached server side.
     * @return <code>true</code> to indicate that the <code>Component</code> is to be cached server side;
     *      otherwise, <code>false</code>.
     */
    boolean     cachedServerSide()      default false;

    /**
     * Returns the event interface (Event Group) associated with this <code>Component</code>.
     * @return the event interface (Event Group) associated with this <code>Component</code>.
     */
    Class<?>    eventGroup()            default Object.class;
}
